package com.example.yin.service.impl;

import com.example.yin.common.SuccessMessage;
import com.example.yin.constant.RedisConstant;
import com.example.yin.dao.ConsumerMapper;
import com.example.yin.domain.Consumer;
import com.example.yin.common.HttpStatusEnum;
import com.example.yin.domain.LoginUser;
import com.example.yin.domain.ResponseResult;
import com.example.yin.service.ConsumerService;
import com.example.yin.service.LoginService;
import com.example.yin.utils.JwtUtil;
import com.example.yin.utils.RedisCache;
import com.example.yin.utils.StringUtil;
import com.example.yin.vo.LoginParamVo;
import com.example.yin.vo.R;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Objects;

@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ConsumerService consumerService;
    @Autowired
    private ConsumerMapper consumerMapper;


    @Override
    public Object login(Consumer user) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if(Objects.isNull(authenticate)){
            throw new RuntimeException("用户名或密码错误");
        }
        //使用userid生成token
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        String userId = loginUser.getUser().getId().toString();
        String jwt = JwtUtil.createJWT(userId);
        //authenticate存入redis
        redisCache.setCacheObject("login:"+userId,loginUser);
        //把token响应给前端
        HashMap<String,Object> map = new HashMap<>();
        map.put("token",jwt);
        map.put("user",loginUser.getUser());
        //return new ResponseResult(200,"登陆成功",map);
        return new SuccessMessage<HashMap<String,Object>>("登陆成功", map).getMessage();
    }

    @Override
    public ResponseResult loginFail(){
        return new ResponseResult(400,"登录失败");
    }

    // 找回密码
    @Override
    public R findPassword(LoginParamVo loginParamVo) {
        if (loginParamVo == null)
            return R.error(HttpStatusEnum.PARAM_ILLEGAL);

        // 获取参数
        String email = loginParamVo.getEmail();
        String password = loginParamVo.getPassword();
        String code = loginParamVo.getCode();

        if (StringUtils.isAnyBlank(email, password, code)) {
            // 非空
            return R.error(HttpStatusEnum.PARAM_ILLEGAL);
        }else if (!StringUtil.checkEmail(email)) {
            // 邮箱格式校验
            return R.error(HttpStatusEnum.EMAIL_ERROR);
        }else if (!StringUtil.checkPassword(password)) {
            // 密码格式和验证码长度校验
            return R.error(HttpStatusEnum.PASSWORD_ERROR);
        }else if(code.length() != 6){
            return R.error(HttpStatusEnum.CODE_ERROR);
        }

        Consumer user =consumerService.selectByEmail(email);
        if (user == null) {
            return R.error(HttpStatusEnum.USER_NOT_EXIST);
        }

        // 获取正确的验证码
        String rightCode = redisTemplate.opsForValue().get(RedisConstant.EMAIL + email).toString();
        if (!code.equals(rightCode)) {
            // 验证码比对
            return R.error(HttpStatusEnum.CODE_ERROR);
        }

        // 删除验证码
        redisTemplate.delete(RedisConstant.EMAIL + email);

        // 修改密码
        Consumer user1 = new Consumer();
        user1.setId(user.getId());
        user1.setPassword(DigestUtils.md5Hex(password));

        boolean res = consumerService.updateUserMsg(user1);
        if(res){
            return R.ok();
        }else{
            return R.error(HttpStatusEnum.UNKNOWN_ERROR);
        }
    }

    @Override
    public Object logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        Integer userid = loginUser.getUser().getId();
        redisCache.deleteObject("login:"+userid);
        return new SuccessMessage("退出成功").getMessage();
    }
}